package com.edu.controller;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URLEncoder;

/*
 * @Author:princess
 * @Date 2023/11/28 11 28 18:52
 *
 */
@Controller
public class DownloadController {
    /*
        基于ServletAPI的下载，本质上是操控响应对象获取输出流，把要下载的文件，通过io操作
        写回到用户的客户端，并告知浏览器打开方式(attachment附件)以及文件名
     */
    @RequestMapping("/download01")
    public void download01(HttpServletRequest request,HttpServletResponse response) throws IOException {
        //获取要下载的文件的真实路径指的是(从盘符开始的路径)
        String realPath = request.getServletContext().getRealPath("/file/copy.txt");
        //创建一个File表示要被下载的文件路径
        File file = new File(realPath);
        //创建输入流来读取文件
        FileInputStream ins = new FileInputStream(file);
        //设定响应的格式，告知输出流的文件以附件的形式打开，URLEncoder确保下载的文件名中文正常显示
        response.setHeader("content-disposition","attachment;fileName="+ URLEncoder.encode(file.getName(),"utf-8"));
        //获取用于客户端返回数据的输出流
        ServletOutputStream oos = response.getOutputStream();
        //创建一个缓冲区用于装每次从输入流中读出来的信息，缓冲区可以减少磁盘io的次数
        byte[] buffer = new byte[1024];
        //文件复制
        int len = 0;
        while ((len = ins.read(buffer)) != -1){
            oos.write(buffer,0,len);
        }
        ins.close();
        oos.close();
    }

    /*
        基于Spring提供的ResponseEntity进行下载
        ResponseEntity用于表示返回的实体
        潜在风险：一次性获取完整的输入流中的数据，有可能造成内存溢出
     */
    @RequestMapping("/download02")
    public ResponseEntity<byte[]> download02(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //获取要下载的文件的真实路径指的是(从盘符开始的路径)
        String realPath = request.getServletContext().getRealPath("/file/copy.txt");
        //创建一个File表示要被下载的文件路径
        File file = new File(realPath);
        //创建一个http头文件
        HttpHeaders headers = new HttpHeaders();
        //头文件中设置客户端浏览器发开方式
        headers.set("content-disposition","attachment;fileName="+ URLEncoder.encode(file.getName(),"utf-8"));
        //创建对下载文件的输入流
        FileInputStream ins = new FileInputStream(file);
        //创建一个返回实体，并返回，需要传入完整的输入流的数据，响应头和响应码
        byte[] bytes = new byte[ins.available()];
        ins.read(bytes);
        return new ResponseEntity<byte[]>(bytes,headers, HttpStatus.OK);
    }
}
